using System;

// 动态数组测试类
public class DynamicArrayTest
{
    public static void RunTest()
    {
        DyArray<int> dyArray = new(7);
        int[] values = new int[] { 1, 2, 3, 4, 5, 6, 7 };
        dyArray.AddValueFast(values);
        Console.WriteLine("当前数组长度为:" + dyArray.Count);

        for (int i = 0; i < dyArray.Count; i++)
        {
            Console.WriteLine($"当前{i}:{dyArray.GetValueWithIndex(i)}");
        }

        Console.WriteLine("\n按 Enter 键继续测试...");
        Console.ReadLine();

        // 测试动态扩容
        dyArray.AddValue(10);
        Console.WriteLine("===============动态扩容====================");
        Console.WriteLine("当前数组长度为:" + dyArray.GetLength());
        Console.WriteLine("当前数组实际元素数:" + dyArray.Count);

        Console.WriteLine("\n按 Enter 键继续测试...");
        Console.ReadLine();

        // 测试删除最后一个
        dyArray.RemoveLastValue();
        Console.WriteLine("===============删除最后一个====================");
        Console.WriteLine("当前数组长度为:" + dyArray.GetLength());
        Console.WriteLine("当前数组实际元素数:" + dyArray.Count);
        for (int i = 0; i < dyArray.Count; i++)
        {
            Console.WriteLine($"当前{i}:{dyArray.GetValueWithIndex(i)}");
        }

        Console.WriteLine("\n按 Enter 键继续测试...");
        Console.ReadLine();

        // 测试删除指定索引
        dyArray.RemoveLastValue();
        dyArray.RemoveLastValue();
        dyArray.RemoveLastValue();
        dyArray.RemoveLastValue();
        dyArray.RemoveLastValue();

        Console.WriteLine("===============删除多个 以验证缩容====================");
        Console.WriteLine("当前数组长度为:" + dyArray.GetLength());
        Console.WriteLine("当前数组实际元素数:" + dyArray.Count);
        for (int i = 0; i < dyArray.Count; i++)
        {
            Console.WriteLine($"当前{i}:{dyArray.GetValueWithIndex(i)}");
        }
    }
}

public class DyArray<T> where T : struct
{
    private T[] Dynamicarray;
    //核心:维护数组的长度
    public int Count;

    public DyArray(int count)
    {
        if (count < 0) count = 0;

        Dynamicarray = new T[count];
        this.Count = 0;
    }
    public void AddValueFast(T[] values)
    {
        for (int i = 0; i < values.Length; i++)
        {
            AddValue(values[i]);
        }
    }

    // 增：尾部追加，满则扩容为两倍
    public void AddValue(T t)
    {
        if (IsInVailedSize()) return;
        //检查扩容
        DilatationSize();

        Dynamicarray[Count] = t;
        Count++;
    }

    public void RemoveLastValue()
    {
        if (Count <= 0) return;
        Dynamicarray[Count - 1] = default(T);
        Count--;

        ReduceSize();
    }
    public void RemoveValueWithIndex(int index)
    {
        if (IsInVailedIndex(index)) return;

        //左移数据
        for (int i = index; i < Count - 1; i++)
        {
            Dynamicarray[i] = Dynamicarray[i + 1];
        }

        Count--;
        Dynamicarray[Count] = default(T);

        //检查缩容
        ReduceSize();
    }


    /// <summary>
    /// 检查索引是否合法 无效返回true
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    private bool IsInVailedIndex(int index)
    {
        if (index < 0 || index >= Count) return true;
        return false;
    }

    /// <summary>
    /// 检查数组大小是否合法 无效返回true
    /// </summary>
    /// <returns></returns>
    private bool IsInVailedSize()
    {
        if (Count < 0) return true;
        return false;
    }

    public T GetValueWithIndex(int index)
    {
        if (IsInVailedIndex(index)) return default(T);
        return Dynamicarray[index];
    }

    public void SetValueWithIndex(int index, T value)
    {
        if (IsInVailedIndex(index)) return;
        Dynamicarray[index] = value;
    }

    public int GetLength() =>Dynamicarray.Length;

    /// <summary>
    /// 扩容
    /// </summary>
    /// <param name="dilatationFactor">扩容系数</param>
    public void DilatationSize(int dilatationFactor = 2)
    {
        if (Count >= Dynamicarray.Length)
        {
            int newCapacity = Dynamicarray.Length * dilatationFactor;
            if (newCapacity == 0) newCapacity = 4;

            T[] newArray = new T[newCapacity];
            System.Array.Copy(Dynamicarray, 0, newArray, 0, Count);
            Dynamicarray = newArray;
        }

    }

    /// <summary>
    /// 缩容
    /// </summary>
    /// <param name="checkLine">检查比例</param>
    /// <param name="ruduceFactor">缩小系数</param>
    public void ReduceSize(int checkLine = 4,int ruduceFactor = 2)
    {   
        //如果当前Count数量小于数组长度的 1/4 则缩小数组长度为原来的一半
        if (Count < Dynamicarray.Length / checkLine)
        {
            int newCapacity = Dynamicarray.Length / ruduceFactor;
            //如果缩小后的长度为0，则设置为4
            if (newCapacity == 0) newCapacity = 4;

            T[] newArray = new T[newCapacity];
            System.Array.Copy(Dynamicarray, 0, newArray, 0, Count);

            Dynamicarray = newArray;
        }
    }
}
